﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using SceneUnpacker.Schematrix;
using SceneUnpacker.se.gno.Properties;

namespace SceneUnpacker.se.gno
{
    public class Unpacker : Form
    {
        private readonly ArchiveCollection _archives = new ArchiveCollection();
        private bool _collapsed;
        private bool _processCanceled;
        private CheckBox appendPrefix;
        private CheckBox appendSourceName;
        private NumericUpDown archiveDepth;
        private CheckedListBox archives;
        private Label archivesCount;
        private CheckBox archivesSelectionControl;
        private Button cancelCommnad;
        private IContainer components;
        private ToolStripStatusLabel currentArchive;
        private ToolStripStatusLabel currentFile;
        private ToolStripStatusLabel currentFileBw;
        private ToolStripStatusLabel currentFileExtracted;
        private ToolStripStatusLabel currentFilePercentage;
        private ToolStripStatusLabel currentVolume;
        public const string DEFAULT_NAME = "Scene Unpacker";
        private ToolStripStatusLabel elapsed;
        private TextBox extraContent;
        private ToolStripStatusLabel fileElapsed;
        private ToolStripProgressBar fileProgress;
        private FolderBrowserDialog folderBrowserDialog1;
        private GroupBox groupBox1;
        private GroupBox groupBox2;
        private GroupBox input;
        private Label label1;
        private Label label2;
        private Label label3;
        private Label label4;
        private Label label6;
        private ToolStripProgressBar overallProgress;
        private Button pauseCommand;
        private Timer processTimer;
        private TextBox sourceFolder;
        private Button sourceFolderBrowse;
        private Button startCommand;
        private StatusStrip statusStrip1;
        private StatusStrip statusStrip2;
        private Button targetBrowse;
        private ComboBox targetFolder;
        private FolderBrowserDialog targetFolderBrowser;
        private ToolTip toolTip1;

        public Unpacker ()
        {
            this.InitializeComponent();
            this.folderBrowserDialog1.ShowNewFolderButton = true;
            this.folderBrowserDialog1.Description = "Select the folder containing your archives.";
            this.targetFolderBrowser.ShowNewFolderButton = true;
            this.targetFolderBrowser.Description = "Select target folder.";
            new DragDropSupport( this, new DragDropSupport.DropHandler( this.sourceFolder_Drop ) );
            new DragDropSupport( this.targetFolder, new DragDropSupport.DropHandler( this.targetFolder_Drop ) );
            this._archives.ExtraContent = this.extraContent.Text = Settings.Default.ExtraContent;
            this._archives.ContentChanged += new ContentChangedHandler( this.archiveCollection_ContentChanged );
            this._archives.ArchiveFound += new ArchiveFoundHandler( this.archiveCollection_ArchiveFound );
            this._archives.DestinationChanged += new DestinationChangedHandler( this.archiveCollection_DestinationChanged );
            this._archives.ProcessStarted += new ProcessStartedHandler( this.archiveCollection_ProcessStarted );
            this._archives.ProcessNextArchive += new NewArchiveHandler( this.archiveCollection_ProcessNextArchive );
            this._archives.ArchiveProcessed += new ArchiveProcessedHandler( this.archiveCollection_ArchiveProcessed );
            this._archives.ProcessEnded += new ProcessEndedHandler( this.archiveCollection_ProcessEnded );
            Marc.WindowStateMonitor.WindowStateMonitor monitor = new Marc.WindowStateMonitor.WindowStateMonitor( this );
            monitor.Maximized += new EventHandler( this.form_Maximized );
            monitor.Normalized += new EventHandler( this.form_Normalized );
            if (Settings.Default.Destinations != null)
            {
                string[] array = new string[Settings.Default.Destinations.Count];
                Settings.Default.Destinations.CopyTo( array, 0 );
                this.targetFolder.Items.AddRange( array );
                if (( this.targetFolder.Text == string.Empty ) && ( this.targetFolder.Items.Count != 0 ))
                {
                    this.targetFolder.SelectedIndex = Settings.Default.Destinations_SelectedIndex;
                }
            }
            this.appendSourceName.Checked = Settings.Default.Append_SourceName;
            this.appendPrefix.Checked = Settings.Default.Append_Prefix;
            this.archiveDepth.Value = Settings.Default.ArchiveDepth;
            this.sourceFolder.Text = this.GetDefaultFolder().ToString();
        }

        private void AddArchive ( Archive a )
        {
            if (this.archives.InvokeRequired)
            {
                AddArchiveCallback method = new AddArchiveCallback( this.AddArchive );
                this.archives.Invoke( method, new object[] { a } );
            }
            else
            {
                this.archives.Items.Add( a, true );
            }
        }

        private void archiveCollection_ArchiveFound ( object sender, Archive a )
        {
            this.AddArchive( a );
        }

        private void archiveCollection_ArchiveProcessed ( object sender, Archive a )
        {
            if (this.statusStrip1.InvokeRequired)
            {
                this.statusStrip1.Invoke( new PerformStepDelegate( this.PerformStep ) );
            }
            else
            {
                this.overallProgress.PerformStep();
            }
        }

        private void archiveCollection_ContentChanged ( ArchiveCollection sender )
        {
            string str = ( sender.Source == null ) ? string.Empty : sender.Source.ToString();
            if (!str.Equals( "." ) && !str.Equals( this.sourceFolder.Text ))
            {
                this.sourceFolder.Text = str;
            }
            this.Text = ( sender.Source != null ) ? sender.Source.Name : string.Empty;
            this.archives.Items.Clear();
            Application.DoEvents();
        }

        private void archiveCollection_DestinationChanged ( ArchiveCollection sender, DirectoryInfo newDestination )
        {
            string str = ( newDestination == null ) ? string.Empty : newDestination.ToString();
            if (!str.Equals( "." ) && !str.Equals( this.targetFolder.Text ))
            {
                this.targetFolder.Text = newDestination.ToString();
            }
        }

        private void archiveCollection_ProcessEnded ( ArchiveCollection sender )
        {
            if (base.InvokeRequired)
            {
                base.Invoke( new ProcessEndedDelegate( this.archiveCollection_ProcessEnded ), new object[] { sender } );
            }
            else
            {
                this.processTimer.Stop();
                this.processTimer = null;
                this.UpdateElapsedTime();
                this.startCommand.Enabled = true;
                this.pauseCommand.Enabled = false;
                this.cancelCommnad.Enabled = false;
                this.input.Enabled = true;
            }
        }

        private void archiveCollection_ProcessNextArchive ( object sender, Archive a )
        {
            if (base.InvokeRequired)
            {
                base.Invoke( new ProcessNextArchiveDelegate( this.archiveCollection_ProcessNextArchive ), new object[] { sender, a } );
            }
            else
            {
                this.currentArchive.Text = a.ToString();
                this.fileProgress.Value = 0;
                this.fileProgress.Visible = true;
                this.AttachHandlers( a.Unrar );
                int index = this.archives.Items.IndexOf( a );
                this.archives.SetSelected( index, true );
            }
        }

        private void archiveCollection_ProcessStarted ( ArchiveCollection sender )
        {
            if (base.InvokeRequired)
            {
                base.Invoke( new ProcessStartedDelegate( this.archiveCollection_ProcessStarted ), new object[] { sender } );
            }
            else
            {
                this.overallProgress.Step = 100 / sender.ArchivesCount;
                this.overallProgress.Value = 0;
                this.overallProgress.Visible = true;
                this._processCanceled = false;
                this.startCommand.Enabled = false;
                this.pauseCommand.Enabled = true;
                this.cancelCommnad.Enabled = true;
                this.input.Enabled = false;
                this.processTimer = new Timer( this.components );
                this.processTimer.Interval = 100;
                this.processTimer.Tick += new EventHandler( this.processTimer_Tick );
                this.processTimer.Start();
            }
        }

        private void archiveInput_TextChanged ( object sender, EventArgs e )
        {
            string text = this.sourceFolder.Text;
            if (text != string.Empty)
            {
                try
                {
                    DirectoryInfo info = new DirectoryInfo( text );
                    this._archives.Source = info;
                }
                catch
                {
                    this._archives.Source = null;
                }
            }
        }

        private void archives_ItemCheck ( object sender, ItemCheckEventArgs e )
        {
            int num = this.archives.CheckedItems.Count + ( ( e.NewValue == CheckState.Checked ) ? 1 : -1 );
            this.archivesCount.Text = string.Concat( new object[] { "", num, "(", this.archives.Items.Count, ")" } );
            this.archivesSelectionControl.CheckState = ( num == 0 ) ? CheckState.Unchecked : ( ( num == this.archives.Items.Count ) ? CheckState.Checked : CheckState.Indeterminate );
            this.startCommand.Enabled = num > 0;
        }

        private void archivesSelectionControl_Click ( object sender, EventArgs e )
        {
            if (this.archivesSelectionControl.CheckState == CheckState.Indeterminate)
            {
                this.archivesSelectionControl.CheckState = CheckState.Unchecked;
            }
        }

        private void AttachHandlers ( Unrar unrar )
        {
            unrar.NewFile += new NewFileHandler( this.unrar_NewFile );
            unrar.NewVolume += new NewVolumeHandler( this.unrar_NewVolume );
            unrar.ExtractionProgress += new ExtractionProgressHandler( this.unrar_ExtractionProgress );
            unrar.MissingVolume += new MissingVolumeHandler( this.unrar_MissingVolume );
            unrar.PasswordRequired += new PasswordRequiredHandler( this.unrar_PasswordRequired );
            unrar.OutOfDiskSpace += new OutOfDiskSpaceHandler( this.unrar_OutOfDiskSpace );
        }

        internal bool BrowseSourceFolder ()
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.SelectedPath = this.GetDefaultFolder().ToString();
            if (dialog.ShowDialog( this ) == DialogResult.OK)
            {
                string selectedPath = dialog.SelectedPath;
                this._archives.Source = new DirectoryInfo( selectedPath );
                Settings.Default.ArchiveSource = selectedPath;
                return true;
            }
            return false;
        }

        private void button5_Click ( object sender, EventArgs e )
        {
            if (this.targetFolder.Text != string.Empty)
            {
                this.targetFolderBrowser.SelectedPath = this.targetFolder.Text;
            }
            if (this.targetFolderBrowser.ShowDialog( this ) == DialogResult.OK)
            {
                if (!this.targetFolder.Items.Contains( this.targetFolderBrowser.SelectedPath ))
                {
                    this.targetFolder.Items.Insert( 0, this.targetFolderBrowser.SelectedPath );
                }
                this._archives.Destination = new DirectoryInfo( this.targetFolderBrowser.SelectedPath );
            }
        }

        private void cancelCommnad_Click ( object sender, EventArgs e )
        {
            this._processCanceled = true;
        }

        private void checkBox1_CheckedChanged ( object sender, EventArgs e )
        {
            if (this._archives != null)
            {
                this._archives.AppendArchivePrefix = this.appendPrefix.Checked;
            }
        }

        private void checkBox2_CheckedChanged ( object sender, EventArgs e )
        {
            if (this.archivesSelectionControl.CheckState != CheckState.Indeterminate)
            {
                base.SuspendLayout();
                bool flag = this.archivesSelectionControl.Checked;
                for (int i = 0; i < this.archives.Items.Count; i++)
                {
                    this.archives.SetItemChecked( i, flag );
                }
                base.ResumeLayout();
            }
        }

        private void ClearArchives ()
        {
            if (this.archives.InvokeRequired)
            {
                ClearArchivesCallback method = new ClearArchivesCallback( this.ClearArchives );
                this.archives.Invoke( method, new object[0] );
            }
            else
            {
                this.archives.Items.Clear();
            }
        }

        protected override void Dispose ( bool disposing )
        {
            if (disposing && ( this.components != null ))
            {
                this.components.Dispose();
            }
            base.Dispose( disposing );
        }

        private void extraContent_TextChanged ( object sender, EventArgs e )
        {
            this._archives.ExtraContent = this.extraContent.Text;
        }

        private void form_Maximized ( object sender, EventArgs e )
        {
            this.statusStrip1.SizingGrip = false;
        }

        private void form_Normalized ( object sender, EventArgs e )
        {
            this.statusStrip1.SizingGrip = true;
        }

        internal DirectoryInfo GetDefaultFolder ()
        {
            string path = ( this._archives.Source != null ) ? this._archives.Source.FullName : Settings.Default.ArchiveSource;
            if (path == string.Empty)
            {
                path = Environment.GetFolderPath( Environment.SpecialFolder.Personal );
            }
            while (( path != string.Empty ) && !Directory.Exists( path ))
            {
                path = Directory.GetParent( path ).ToString();
            }
            return new DirectoryInfo( path );
        }

        private void InitializeComponent ()
        {
            this.cancelCommnad = new System.Windows.Forms.Button();
            this.pauseCommand = new System.Windows.Forms.Button();
            this.startCommand = new System.Windows.Forms.Button();
            this.label3 = new System.Windows.Forms.Label();
            this.appendSourceName = new System.Windows.Forms.CheckBox();
            this.targetBrowse = new System.Windows.Forms.Button();
            this.archives = new System.Windows.Forms.CheckedListBox();
            this.sourceFolderBrowse = new System.Windows.Forms.Button();
            this.sourceFolder = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
            this.targetFolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
            this.input = new System.Windows.Forms.GroupBox();
            this.archivesSelectionControl = new System.Windows.Forms.CheckBox();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.label2 = new System.Windows.Forms.Label();
            this.extraContent = new System.Windows.Forms.TextBox();
            this.archivesCount = new System.Windows.Forms.Label();
            this.label6 = new System.Windows.Forms.Label();
            this.archiveDepth = new System.Windows.Forms.NumericUpDown();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.appendPrefix = new System.Windows.Forms.CheckBox();
            this.label4 = new System.Windows.Forms.Label();
            this.targetFolder = new System.Windows.Forms.ComboBox();
            this.statusStrip1 = new System.Windows.Forms.StatusStrip();
            this.currentFile = new System.Windows.Forms.ToolStripStatusLabel();
            this.currentFileExtracted = new System.Windows.Forms.ToolStripStatusLabel();
            this.currentFilePercentage = new System.Windows.Forms.ToolStripStatusLabel();
            this.currentFileBw = new System.Windows.Forms.ToolStripStatusLabel();
            this.fileElapsed = new System.Windows.Forms.ToolStripStatusLabel();
            this.fileProgress = new System.Windows.Forms.ToolStripProgressBar();
            this.statusStrip2 = new System.Windows.Forms.StatusStrip();
            this.currentArchive = new System.Windows.Forms.ToolStripStatusLabel();
            this.currentVolume = new System.Windows.Forms.ToolStripStatusLabel();
            this.elapsed = new System.Windows.Forms.ToolStripStatusLabel();
            this.overallProgress = new System.Windows.Forms.ToolStripProgressBar();
            this.input.SuspendLayout();
            this.groupBox2.SuspendLayout();
            ( (System.ComponentModel.ISupportInitialize)( this.archiveDepth ) ).BeginInit();
            this.groupBox1.SuspendLayout();
            this.statusStrip1.SuspendLayout();
            this.statusStrip2.SuspendLayout();
            this.SuspendLayout();
            // 
            // cancelCommnad
            // 
            this.cancelCommnad.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.cancelCommnad.Enabled = false;
            this.cancelCommnad.Location = new System.Drawing.Point( 533, 337 );
            this.cancelCommnad.Name = "cancelCommnad";
            this.cancelCommnad.Size = new System.Drawing.Size( 75, 23 );
            this.cancelCommnad.TabIndex = 5;
            this.cancelCommnad.Text = "Cancel";
            this.cancelCommnad.UseVisualStyleBackColor = true;
            this.cancelCommnad.Click += new System.EventHandler( this.cancelCommnad_Click );
            // 
            // pauseCommand
            // 
            this.pauseCommand.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.pauseCommand.Enabled = false;
            this.pauseCommand.Location = new System.Drawing.Point( 611, 337 );
            this.pauseCommand.Name = "pauseCommand";
            this.pauseCommand.Size = new System.Drawing.Size( 75, 23 );
            this.pauseCommand.TabIndex = 6;
            this.pauseCommand.Text = "Pause";
            this.pauseCommand.UseVisualStyleBackColor = true;
            // 
            // startCommand
            // 
            this.startCommand.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.startCommand.Enabled = false;
            this.startCommand.Location = new System.Drawing.Point( 452, 337 );
            this.startCommand.Name = "startCommand";
            this.startCommand.Size = new System.Drawing.Size( 75, 23 );
            this.startCommand.TabIndex = 0;
            this.startCommand.Text = "Start";
            this.startCommand.UseVisualStyleBackColor = true;
            this.startCommand.Click += new System.EventHandler( this.startCommand_Click );
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point( 6, 56 );
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size( 51, 13 );
            this.label3.TabIndex = 6;
            this.label3.Text = "Archives:";
            // 
            // appendSourceName
            // 
            this.appendSourceName.AutoSize = true;
            this.appendSourceName.Checked = true;
            this.appendSourceName.CheckState = System.Windows.Forms.CheckState.Checked;
            this.appendSourceName.Location = new System.Drawing.Point( 6, 17 );
            this.appendSourceName.Name = "appendSourceName";
            this.appendSourceName.Size = new System.Drawing.Size( 125, 17 );
            this.appendSourceName.TabIndex = 5;
            this.appendSourceName.Text = "Last part from source";
            this.appendSourceName.UseVisualStyleBackColor = true;
            this.appendSourceName.CheckedChanged += new System.EventHandler( this.targetCreate_CheckedChanged );
            // 
            // targetBrowse
            // 
            this.targetBrowse.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.targetBrowse.Location = new System.Drawing.Point( 602, 257 );
            this.targetBrowse.Name = "targetBrowse";
            this.targetBrowse.Size = new System.Drawing.Size( 75, 23 );
            this.targetBrowse.TabIndex = 10;
            this.targetBrowse.Text = "Browse...";
            this.targetBrowse.UseVisualStyleBackColor = true;
            this.targetBrowse.Click += new System.EventHandler( this.button5_Click );
            // 
            // archives
            // 
            this.archives.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( ( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom )
                        | System.Windows.Forms.AnchorStyles.Left )
                        | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.archives.CheckOnClick = true;
            this.archives.FormattingEnabled = true;
            this.archives.HorizontalScrollbar = true;
            this.archives.Location = new System.Drawing.Point( 9, 73 );
            this.archives.MinimumSize = new System.Drawing.Size( 4, 24 );
            this.archives.Name = "archives";
            this.archives.Size = new System.Drawing.Size( 666, 154 );
            this.archives.Sorted = true;
            this.archives.TabIndex = 7;
            this.archives.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler( this.archives_ItemCheck );
            // 
            // sourceFolderBrowse
            // 
            this.sourceFolderBrowse.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.sourceFolderBrowse.Location = new System.Drawing.Point( 602, 29 );
            this.sourceFolderBrowse.Name = "sourceFolderBrowse";
            this.sourceFolderBrowse.Size = new System.Drawing.Size( 75, 23 );
            this.sourceFolderBrowse.TabIndex = 3;
            this.sourceFolderBrowse.Text = "Browse...";
            this.sourceFolderBrowse.UseVisualStyleBackColor = true;
            this.sourceFolderBrowse.Click += new System.EventHandler( this.sourceFolderBrowse_Click );
            // 
            // sourceFolder
            // 
            this.sourceFolder.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left )
                        | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.sourceFolder.Location = new System.Drawing.Point( 9, 32 );
            this.sourceFolder.Name = "sourceFolder";
            this.sourceFolder.Size = new System.Drawing.Size( 587, 20 );
            this.sourceFolder.TabIndex = 2;
            this.sourceFolder.TextChanged += new System.EventHandler( this.archiveInput_TextChanged );
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point( 6, 16 );
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size( 44, 13 );
            this.label1.TabIndex = 1;
            this.label1.Text = "Source:";
            // 
            // input
            // 
            this.input.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( ( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom )
                        | System.Windows.Forms.AnchorStyles.Left )
                        | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.input.Controls.Add( this.archivesSelectionControl );
            this.input.Controls.Add( this.groupBox2 );
            this.input.Controls.Add( this.archivesCount );
            this.input.Controls.Add( this.label6 );
            this.input.Controls.Add( this.archiveDepth );
            this.input.Controls.Add( this.groupBox1 );
            this.input.Controls.Add( this.label4 );
            this.input.Controls.Add( this.label1 );
            this.input.Controls.Add( this.sourceFolder );
            this.input.Controls.Add( this.targetBrowse );
            this.input.Controls.Add( this.targetFolder );
            this.input.Controls.Add( this.label3 );
            this.input.Controls.Add( this.sourceFolderBrowse );
            this.input.Controls.Add( this.archives );
            this.input.Location = new System.Drawing.Point( 3, 3 );
            this.input.Name = "input";
            this.input.Size = new System.Drawing.Size( 683, 328 );
            this.input.TabIndex = 16;
            this.input.TabStop = false;
            this.input.Text = "Input";
            // 
            // archivesSelectionControl
            // 
            this.archivesSelectionControl.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.archivesSelectionControl.AutoSize = true;
            this.archivesSelectionControl.Location = new System.Drawing.Point( 638, 55 );
            this.archivesSelectionControl.Name = "archivesSelectionControl";
            this.archivesSelectionControl.Size = new System.Drawing.Size( 37, 17 );
            this.archivesSelectionControl.TabIndex = 19;
            this.archivesSelectionControl.Text = "All";
            this.archivesSelectionControl.ThreeState = true;
            this.archivesSelectionControl.UseVisualStyleBackColor = true;
            this.archivesSelectionControl.CheckStateChanged += new System.EventHandler( this.checkBox2_CheckedChanged );
            this.archivesSelectionControl.Click += new System.EventHandler( this.archivesSelectionControl_Click );
            // 
            // groupBox2
            // 
            this.groupBox2.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left )
                        | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.groupBox2.Controls.Add( this.label2 );
            this.groupBox2.Controls.Add( this.extraContent );
            this.groupBox2.Location = new System.Drawing.Point( 262, 285 );
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size( 415, 38 );
            this.groupBox2.TabIndex = 18;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Also include";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point( 6, 18 );
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size( 52, 13 );
            this.label2.TabIndex = 1;
            this.label2.Text = "Wildcard:";
            // 
            // extraContent
            // 
            this.extraContent.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left )
                        | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.extraContent.Location = new System.Drawing.Point( 61, 15 );
            this.extraContent.Name = "extraContent";
            this.extraContent.Size = new System.Drawing.Size( 348, 20 );
            this.extraContent.TabIndex = 0;
            this.extraContent.TextChanged += new System.EventHandler( this.extraContent_TextChanged );
            // 
            // archivesCount
            // 
            this.archivesCount.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.archivesCount.Location = new System.Drawing.Point( 576, 56 );
            this.archivesCount.Name = "archivesCount";
            this.archivesCount.Size = new System.Drawing.Size( 56, 13 );
            this.archivesCount.TabIndex = 15;
            this.archivesCount.Text = "0(0)";
            this.archivesCount.TextAlign = System.Drawing.ContentAlignment.TopRight;
            // 
            // label6
            // 
            this.label6.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point( 593, 11 );
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size( 39, 13 );
            this.label6.TabIndex = 14;
            this.label6.Text = "Depth:";
            // 
            // archiveDepth
            // 
            this.archiveDepth.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.archiveDepth.Location = new System.Drawing.Point( 638, 9 );
            this.archiveDepth.Maximum = new decimal( new int[] {
            10,
            0,
            0,
            0} );
            this.archiveDepth.Minimum = new decimal( new int[] {
            1,
            0,
            0,
            -2147483648} );
            this.archiveDepth.Name = "archiveDepth";
            this.archiveDepth.Size = new System.Drawing.Size( 39, 20 );
            this.archiveDepth.TabIndex = 13;
            this.archiveDepth.Value = new decimal( new int[] {
            2,
            0,
            0,
            0} );
            this.archiveDepth.ValueChanged += new System.EventHandler( this.numericUpDown1_ValueChanged );
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left ) ) );
            this.groupBox1.Controls.Add( this.appendSourceName );
            this.groupBox1.Controls.Add( this.appendPrefix );
            this.groupBox1.Location = new System.Drawing.Point( 9, 285 );
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size( 244, 37 );
            this.groupBox1.TabIndex = 12;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Append";
            // 
            // appendPrefix
            // 
            this.appendPrefix.AutoSize = true;
            this.appendPrefix.Location = new System.Drawing.Point( 136, 17 );
            this.appendPrefix.Name = "appendPrefix";
            this.appendPrefix.Size = new System.Drawing.Size( 102, 17 );
            this.appendPrefix.TabIndex = 11;
            this.appendPrefix.Text = "Prefix of archive";
            this.appendPrefix.UseVisualStyleBackColor = true;
            this.appendPrefix.CheckedChanged += new System.EventHandler( this.checkBox1_CheckedChanged );
            // 
            // label4
            // 
            this.label4.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left ) ) );
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point( 6, 243 );
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size( 63, 13 );
            this.label4.TabIndex = 8;
            this.label4.Text = "Destination:";
            // 
            // targetFolder
            // 
            this.targetFolder.AllowDrop = true;
            this.targetFolder.Anchor = ( (System.Windows.Forms.AnchorStyles)( ( ( System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left )
                        | System.Windows.Forms.AnchorStyles.Right ) ) );
            this.targetFolder.FormattingEnabled = true;
            this.targetFolder.Location = new System.Drawing.Point( 9, 259 );
            this.targetFolder.Name = "targetFolder";
            this.targetFolder.Size = new System.Drawing.Size( 587, 21 );
            this.targetFolder.TabIndex = 9;
            this.targetFolder.TextChanged += new System.EventHandler( this.targetFolder_TextUpdate );
            // 
            // statusStrip1
            // 
            this.statusStrip1.Items.AddRange( new System.Windows.Forms.ToolStripItem[] {
            this.currentFile,
            this.currentFileExtracted,
            this.currentFilePercentage,
            this.currentFileBw,
            this.fileElapsed,
            this.fileProgress} );
            this.statusStrip1.Location = new System.Drawing.Point( 0, 390 );
            this.statusStrip1.Name = "statusStrip1";
            this.statusStrip1.Size = new System.Drawing.Size( 692, 24 );
            this.statusStrip1.TabIndex = 14;
            this.statusStrip1.Text = "statusStrip1";
            // 
            // currentFile
            // 
            this.currentFile.Name = "currentFile";
            this.currentFile.Overflow = System.Windows.Forms.ToolStripItemOverflow.Never;
            this.currentFile.Size = new System.Drawing.Size( 17, 19 );
            this.currentFile.Text = "--";
            this.currentFile.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.currentFile.ToolTipText = "Text";
            // 
            // currentFileExtracted
            // 
            this.currentFileExtracted.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right;
            this.currentFileExtracted.Name = "currentFileExtracted";
            this.currentFileExtracted.Size = new System.Drawing.Size( 21, 19 );
            this.currentFileExtracted.Text = "--";
            // 
            // currentFilePercentage
            // 
            this.currentFilePercentage.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right;
            this.currentFilePercentage.Name = "currentFilePercentage";
            this.currentFilePercentage.Size = new System.Drawing.Size( 21, 19 );
            this.currentFilePercentage.Text = "--";
            // 
            // currentFileBw
            // 
            this.currentFileBw.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right;
            this.currentFileBw.Name = "currentFileBw";
            this.currentFileBw.Size = new System.Drawing.Size( 21, 19 );
            this.currentFileBw.Text = "--";
            // 
            // fileElapsed
            // 
            this.fileElapsed.Name = "fileElapsed";
            this.fileElapsed.Size = new System.Drawing.Size( 597, 19 );
            this.fileElapsed.Spring = true;
            this.fileElapsed.Text = "--:--:--";
            this.fileElapsed.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // fileProgress
            // 
            this.fileProgress.Enabled = false;
            this.fileProgress.Name = "fileProgress";
            this.fileProgress.Size = new System.Drawing.Size( 100, 18 );
            this.fileProgress.Visible = false;
            // 
            // statusStrip2
            // 
            this.statusStrip2.Items.AddRange( new System.Windows.Forms.ToolStripItem[] {
            this.currentArchive,
            this.currentVolume,
            this.elapsed,
            this.overallProgress} );
            this.statusStrip2.Location = new System.Drawing.Point( 0, 366 );
            this.statusStrip2.Name = "statusStrip2";
            this.statusStrip2.Size = new System.Drawing.Size( 692, 24 );
            this.statusStrip2.SizingGrip = false;
            this.statusStrip2.TabIndex = 18;
            this.statusStrip2.Text = "statusStrip2";
            // 
            // currentArchive
            // 
            this.currentArchive.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right;
            this.currentArchive.Name = "currentArchive";
            this.currentArchive.Size = new System.Drawing.Size( 21, 19 );
            this.currentArchive.Text = "--";
            this.currentArchive.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // currentVolume
            // 
            this.currentVolume.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right;
            this.currentVolume.Name = "currentVolume";
            this.currentVolume.Size = new System.Drawing.Size( 21, 19 );
            this.currentVolume.Text = "--";
            this.currentVolume.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // elapsed
            // 
            this.elapsed.Name = "elapsed";
            this.elapsed.Size = new System.Drawing.Size( 635, 19 );
            this.elapsed.Spring = true;
            this.elapsed.Text = "--:--:--";
            this.elapsed.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // overallProgress
            // 
            this.overallProgress.Name = "overallProgress";
            this.overallProgress.Size = new System.Drawing.Size( 100, 18 );
            this.overallProgress.Visible = false;
            // 
            // Unpacker
            // 
            this.AllowDrop = true;
            this.ClientSize = new System.Drawing.Size( 692, 414 );
            this.Controls.Add( this.statusStrip2 );
            this.Controls.Add( this.input );
            this.Controls.Add( this.cancelCommnad );
            this.Controls.Add( this.pauseCommand );
            this.Controls.Add( this.startCommand );
            this.Controls.Add( this.statusStrip1 );
            this.DoubleBuffered = true;
            this.MinimumSize = new System.Drawing.Size( 240, 120 );
            this.Name = "Unpacker";
            this.ShowInTaskbar = false;
            this.Text = "Unpacker";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler( this.Unpacker_FormClosing );
            this.Load += new System.EventHandler( this.Unpacker_Load );
            this.input.ResumeLayout( false );
            this.input.PerformLayout();
            this.groupBox2.ResumeLayout( false );
            this.groupBox2.PerformLayout();
            ( (System.ComponentModel.ISupportInitialize)( this.archiveDepth ) ).EndInit();
            this.groupBox1.ResumeLayout( false );
            this.groupBox1.PerformLayout();
            this.statusStrip1.ResumeLayout( false );
            this.statusStrip1.PerformLayout();
            this.statusStrip2.ResumeLayout( false );
            this.statusStrip2.PerformLayout();
            this.ResumeLayout( false );
            this.PerformLayout();

        }

        private void label5_Click ( object sender, EventArgs e )
        {
            if (this._collapsed)
            {
                base.Controls.Add( this.input );
                base.PerformLayout();
            }
            else
            {
                base.Controls.Remove( this.input );
            }
            this._collapsed = !this._collapsed;
        }

        private void numericUpDown1_ValueChanged ( object sender, EventArgs e )
        {
            if (this._archives != null)
            {
                this._archives.MaxDepth = (int)this.archiveDepth.Value;
            }
        }

        private void PerformStep ()
        {
            this.overallProgress.PerformStep();
        }

        private void processTimer_Tick ( object sender, EventArgs e )
        {
            this.UpdateElapsedTime();
        }

        private void SelectArchive ( int i, bool b )
        {
            this.archives.SetSelected( i, true );
        }

        private void sourceFolder_Drop ( DirectoryInfo dir )
        {
            this._archives.Source = null;
            this._archives.Source = dir;
        }

        private void sourceFolderBrowse_Click ( object sender, EventArgs e )
        {
            this.BrowseSourceFolder();
        }

        private void startCommand_Click ( object sender, EventArgs e )
        {
            if (this._archives.Destination == null)
            {
                MessageBox.Show( this, "No destination defined!", "Missing Value", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
            }
            else
            {
                List<Archive> selected = new List<Archive>();
                foreach (object obj2 in this.archives.CheckedItems)
                {
                    selected.Add( (Archive)obj2 );
                }
                try
                {
                    this._archives.AsyncProcess( selected );
                }
                catch (Exception exception)
                {
                    MessageBox.Show( this, exception.Message, "Process Exception", MessageBoxButtons.OK );
                }
            }
        }

        private void targetCreate_CheckedChanged ( object sender, EventArgs e )
        {
            if (this._archives != null)
            {
                this._archives.AppendSourceName = this.appendSourceName.Checked;
            }
        }

        private void targetFolder_Drop ( DirectoryInfo dir )
        {
            this._archives.Destination = dir;
        }

        private void targetFolder_TextUpdate ( object sender, EventArgs e )
        {
            string text = this.targetFolder.Text;
            try
            {
                this._archives.Destination = new DirectoryInfo( text );
            }
            catch (Exception)
            {
                this._archives.Destination = null;
            }
        }

        private void Unpacker_FormClosing ( object sender, FormClosingEventArgs e )
        {
            this._processCanceled = true;
            this._archives.Stop();
            string[] destination = new string[this.targetFolder.Items.Count];
            this.targetFolder.Items.CopyTo( destination, 0 );
            Settings.Default.Destinations.Clear();
            Settings.Default.Destinations.AddRange( destination );
            Settings.Default.Destinations_SelectedIndex = this.targetFolder.SelectedIndex;
            Settings.Default.ExtraContent = this.extraContent.Text;
            Settings.Default.Append_Prefix = this.appendPrefix.Checked;
            Settings.Default.Append_SourceName = this.appendSourceName.Checked;
            Settings.Default.ArchiveDepth = (int)this.archiveDepth.Value;
            Settings.Default.Save();
        }

        private void Unpacker_Load ( object sender, EventArgs e )
        {
        }

        private void unrar_ExtractionProgress ( object sender, ExtractionProgressEventArgs e )
        {
            if (this._processCanceled)
            {
                e.ContinueOperation = false;
            }
        }

        private void unrar_MissingVolume ( object sender, MissingVolumeEventArgs e )
        {
            TextInputDialog dialog = new TextInputDialog();
            dialog.Value = e.VolumeName;
            dialog.Prompt = string.Format( "Volume is missing.  Correct or cancel.", new object[0] );
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                e.VolumeName = dialog.Value;
                e.ContinueOperation = true;
            }
            else
            {
                e.ContinueOperation = false;
            }
        }

        private void unrar_NewFile ( object sender, NewFileEventArgs e )
        {
            if (base.InvokeRequired)
            {
                base.Invoke( new NewFileDelegate( this.unrar_NewFile ), new object[] { sender, e } );
            }
            else
            {
                if (e.fileInfo.FileName.Length > 15)
                {
                    this.currentFile.Text = e.fileInfo.FileName.Substring( 0, 14 ) + "…";
                    this.toolTip1.SetToolTip( this.statusStrip1, e.fileInfo.FileName );
                }
                else
                {
                    this.currentFile.Text = e.fileInfo.FileName;
                    this.toolTip1.SetToolTip( this.statusStrip1, null );
                }
                this.fileProgress.Value = 0;
            }
        }

        private void unrar_NewVolume ( object sender, NewVolumeEventArgs e )
        {
            if (base.InvokeRequired)
            {
                base.Invoke( new NewVolumeDelegate( this.unrar_NewVolume ), new object[] { sender, e } );
            }
            else
            {
                this.currentVolume.Text = new FileInfo( e.VolumeName ).Name;
            }
        }

        private void unrar_OutOfDiskSpace ( object sender, OutOfDiskSpaceEventArgs e )
        {
            if (base.InvokeRequired)
            {
                base.Invoke( new OutOfDiskDelegate( this.unrar_OutOfDiskSpace ), new object[] { sender, e } );
            }
            else if (MessageBox.Show( this, "Disk is running low of storage space \n[" + PathUtils.FormatBytes( e.destInfo.Free ) + " free]", "Unpack problem", MessageBoxButtons.RetryCancel, MessageBoxIcon.Exclamation ) == DialogResult.Cancel)
            {
                e.ContinueOperation = false;
            }
        }

        private void unrar_PasswordRequired ( object sender, PasswordRequiredEventArgs e )
        {
            TextInputDialog dialog = new TextInputDialog();
            dialog.Prompt = string.Format( "Password is required for extraction.", new object[0] );
            dialog.PasswordChar = '*';
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                e.Password = dialog.Value;
                e.ContinueOperation = true;
            }
            else
            {
                e.ContinueOperation = false;
            }
        }

        private void UpdateElapsedTime ()
        {
            if (( this._archives.Statistics != null ) && ( this._archives.Statistics.Split != null ))
            {
                this.fileElapsed.Text = this._archives.Statistics.Split.TimeElapsed.ToString().Substring( 0, 8 );
                this.elapsed.Text = this._archives.Statistics.TimeElapsed.ToString().Substring( 0, 8 );
                this.fileProgress.Value = (int)this._archives.Statistics.Split.PercentCompleate;
                int percentCompleate = (int)this._archives.Statistics.Split.PercentCompleate;
                this.currentFilePercentage.Text = percentCompleate + "%";
                this.currentFileBw.Text = PathUtils.FormatBytes( this._archives.Statistics.Bandwidth ) + "/s (Last " + PathUtils.FormatBytes( this._archives.Statistics.Split.Bandwidth ) + "/s)";
                this.currentFileExtracted.Text = PathUtils.FormatBytes( this._archives.Statistics.Split.BytesExtracted ) + " (" + PathUtils.FormatBytes( this._archives.Statistics.Split.FileSize ) + ")";
            }
        }

        public ArchiveCollection Archives
        {
            get
            {
                return this._archives;
            }
        }

        private delegate void AddArchiveCallback ( Archive item );

        private delegate void ClearArchivesCallback ();

        private delegate void NewFileDelegate ( object sender, NewFileEventArgs e );

        private delegate void NewVolumeDelegate ( object sender, NewVolumeEventArgs e );

        private delegate void OutOfDiskDelegate ( object sender, OutOfDiskSpaceEventArgs e );

        private delegate void PerformStepDelegate ();

        private delegate void ProcessEndedDelegate ( ArchiveCollection sender );

        private delegate void ProcessNextArchiveDelegate ( object sender, Archive a );

        private delegate void ProcessStartedDelegate ( ArchiveCollection sender );
    }
}

